/*
    Copyright 2006,2007,2008 Luigi Auriemma

    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation; either version 2 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program; if not, write to the Free Software
    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA

    http://www.gnu.org/licenses/gpl.txt
*/

#include <mysql/mysql.h>



#define SQLSZ       262144  /* useful to avoid security problems without checks */
#define SQLTIMEOUT  300000



MYSQL   dbase;
u8      *sqlquery;



void sql_fix(u8 *data) {
    u8      *p;

    for(p = data; *p; p++) {
        switch(*p) {
            case '\'':
            case '&':
            case '?':
            case '{':
            case '}':
            case '(':
            case ')':
            case '[':
            case ']':
            case '-':
            case ';':
            case '~':
            case '|':
            case '$':
            case '!':
            case '>':
            case '*':
            case '%':
            case '_':
            case ',': *p = '.'; break;
            default: break;
        }
    }
}



void sql_parse(u8 *data, u8 *limit, u8 *sqlquery) {
    int     nt = 0;
    u8      minitmp[32],
            *p,
            *port,
            *value = NULL;

    port = strchr(data, ':');
    if(!port) return;
    *port++ = 0;

    p = strchr(port, ' ');
    if(!p) return;
    *p++ = 0;
    if(*p == '\\') *p++ = 0;    // avoid possible bug

    replace(sqlquery, "#IP",    data);
    replace(sqlquery, "#PORT",  port);
    sprintf(minitmp,  "%u",     (unsigned)time(NULL));
    replace(sqlquery, "#DATE",  minitmp);

    for(data = p; (data < limit) && (p = strchr(data, '\\')); data = p + 1, nt++) {
        *p = 0;
        sql_fix(data);

        if(nt & 1) {
            if(!quiet) fprintf(fdout, "%s\n", data);
            if(value) replace(sqlquery, value, data);

        } else {
            if(!*data) break;
            if(!quiet) fprintf(fdout, "%28s: ", data);
            value  = data - 1;
            *value = '#';
        }
    }
}



int gssql_init(void) {
    fprintf(fdout, "\n- MySQL server connection\n");

    if(!mysql_init(&dbase)) {
        fprintf(stderr, "\nError: database initialization error\n\n");
        exit(1);
    }
    if(!mysql_real_connect(&dbase, sql_host, sql_username, sql_password, sql_database, 0, NULL, 0)) {
        fprintf(stderr, "\nError: %s\n\n", mysql_error(&dbase));
        exit(1);
    }

    sqlquery = malloc(SQLSZ + 1);
    if(!sqlquery) std_err();

    return(0);
}



int gssql_later(void) {
    if(sql_queryl) {
        if(!quiet) fprintf(fdout, "\n* SQL_LATER:\n  %s\n", sql_queryl);

        if(mysql_real_query(&dbase, sql_queryl, strlen(sql_queryl))) {
            fprintf(stderr, "\nError: %s\n\n", mysql_error(&dbase));
            exit(1);
        }

        if(!mysql_affected_rows(&dbase)) {
            fprintf(stderr, "\nAlert: no rows have been affected by the SQL operation\n\n");
        }
    }
    return(0);
}



int gssql_close(void) {
    mysql_close(&dbase);
    free(sqlquery);
    return(0);
}



int gssql(u8 *data) {
    u8      *limit;

    limit = data + strlen(data);

    if(sql_queryb) {
        strcpy(sqlquery, sql_queryb);
        sql_parse(data, limit, sqlquery);
        if(!quiet) fprintf(fdout, "\n* SQL BEFORE:\n  %s\n", sqlquery);

        if(mysql_real_query(&dbase, sqlquery, strlen(sqlquery))) {
            fprintf(stderr, "\nError: %s\n\n", mysql_error(&dbase));
            exit(1);
        }
        if(mysql_affected_rows(&dbase)) return(0);
        if(!quiet) fprintf(fdout, "* operation failed, continue with the normal query\n");
    }

    strcpy(sqlquery, sql_query);
    sql_parse(data, limit, sqlquery);
    if(!quiet) fprintf(fdout, "\n* SQL:\n  %s\n", sqlquery);

    if(mysql_real_query(&dbase, sqlquery, strlen(sqlquery))) {
        fprintf(stderr, "\nError: %s\n\n", mysql_error(&dbase));
        exit(1);
    }
    if(!mysql_affected_rows(&dbase)) {
        fprintf(stderr, "\nAlert: no rows have been affected by the SQL operation\n\n");
    }
    return(0);
}


